﻿using System;
using System.Text;
using System.Collections ;

namespace MyFastDataSourceBind
{
    /// <summary>
    /// 在属性列表中弹出的列表控件，编写袁永福
    /// </summary>
    public class DesignPopupListBox : System.Windows.Forms.ListBox
    {
/// <summary>
/// 内置的列表项目类型
/// </summary>
private class ListItem
{
    /// <summary>
    /// 列表项目数值
    /// </summary>
    public string Value = null;
    /// <summary>
    /// 列表项目说明
    /// </summary>
    public string Description = null;
    /// <summary>
    /// 显示列表项目的文本
    /// </summary>
    public string DisplayText = null;
    /// <summary>
    /// 返回项目文本
    /// </summary>
    /// <returns>项目文本</returns>
    public override string ToString()
    {
        return DisplayText;
    }
}
/// <summary>
/// 向控件添加列表项目
/// </summary>
/// <param name="Value">列表项目数值</param>
/// <param name="Desc">列表项目说明</param>
public void AddItem(string Value, string Desc)
{
    ListItem item = new ListItem();
    item.Value = Value;
    item.Description = Desc;
    this.Items.Add(item);
}

private System.Windows.Forms.Design.IWindowsFormsEditorService mySvc = null;
/// <summary>
/// 弹出列表控件供用户选择输入
/// </summary>
/// <param name="svc">设计环境服务对象</param>
/// <param name="selectedValue">初始化选择的项目值</param>
/// <returns>用户选择输入的列表项目值，若没有选择则返回空引用</returns>
public string Popup(
    System.Windows.Forms.Design.IWindowsFormsEditorService svc,
    string selectedValue)
{
    int max = 10;
    // 获得GB2312编码格式，获得列表项目数值的最大字节长度
    System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(936);
    foreach (ListItem item in this.Items)
    {
        if (item.Value != null)
        {
            int len = encoding.GetByteCount(item.Value);
            if (len > max)
            {
                max = len;
            }
        }
    }
    max += 2;
    // 设置列表项目显示的文本
    foreach (ListItem item in this.Items)
    {
        if (item.Value != null)
        {
            int len = encoding.GetByteCount(item.Value);
            if (len < max)
            {
                item.DisplayText =
                    item.Value
                    + new string(' ', max - len)
                    + item.Description;
            }
        }
    }
    // 设置当前列表项目
    foreach (ListItem item in this.Items)
    {
        if (selectedValue == item.Value)
        {
            this.SelectedItem = item;
            break;
        }
    }
    // 计算列表项目中最大的显示宽度
    int MaxWidth = 0;
    using (System.Drawing.Graphics g = this.CreateGraphics())
    {
        // 根据控件创建新的画布对象
        foreach (object obj in this.Items)
        {
            // 遍历所有的列表项目获得其显示的文本值
            string txt = this.GetItemText(obj);
            if (txt != null && txt.Length > 0)
            {
                // 计算文本显示宽度
                System.Drawing.SizeF size = g.MeasureString(
                    txt,
                    this.Font,
                    10000,
                    System.Drawing.StringFormat.GenericDefault);
                if (MaxWidth < size.Width)
                {
                    // 设置最大文本显示宽度
                    MaxWidth = (int)size.Width;
                }
            }
        }
    }//using
    System.Drawing.Size psize = this.PreferredSize;
    psize.Width = MaxWidth;
    psize.Height = this.PreferredHeight;
    // 设置控件的宽度不得小于300.
    if (psize.Height > 300)
        psize.Height = 300;
    // 设置列表框控件的客户区大小
    this.ClientSize = psize;

    mySvc = svc;
    // 调用IWindowsFormsEditorService的DropDownControl函数来弹出列表。
    // 此时当前线程就进入DropDownControl函数里面而不立即返回，直到列表
    // 隐藏的才返回。
    svc.DropDownControl(this);
    mySvc = null;
    ListItem item2 = (ListItem)this.SelectedItem;
    if (item2 != null)
    {
        return item2.Value;
    }
    return null;
}
/// <summary>
/// 用户点击控件事件处理，关闭列表项目控件
/// </summary>
/// <param name="e">事件参数</param>
protected override void OnClick(EventArgs e)
{
    base.OnClick(e);
    if (mySvc != null)
    {
        // 用户单击的某个列表项目，调用IWindowsFormsEditorService的CloseDropDown函数
        // 来关闭弹出式的列表，此时就会退出IWindowsFormsEditorService的DropDownControl函数。
        mySvc.CloseDropDown();
    }
}
    }//public class DesignPopupListBox : System.Windows.Forms.ListBox
}